package com.yanghui.lingyue.functions.game.bread

import com.icedata.sika.bridge.*
import com.icedata.sika.core.CommandProcessor
import com.icedata.sika.core.Sika
import com.icedata.sika.database.Column
import com.icedata.sika.database.Table
import com.icedata.sika.util.Logger
import com.yanghui.lingyue.bot.Bot
import com.yanghui.lingyue.data.Command
import com.yanghui.lingyue.data.Operation
import com.yanghui.lingyue.functions.AbstractFunction
import com.yanghui.lingyue.functions.timer.TimeScheduler
import com.yanghui.lingyue.utils.databaseUtils.OperationDatabaseUtils
import com.yanghui.lingyue.utils.functionUtils.FunctionUtils
import com.yanghui.lingyue.utils.timeUtils.TimeUtils
import java.util.*
import java.util.concurrent.ConcurrentHashMap

object Bread : AbstractFunction() {
    override val name: String = "Bread"
    val userBreadMap = ConcurrentHashMap<Long, UserBread>()

    fun init() {
        userBreadMap.clear()
        Bot.sikaCore.databaseCopy<UserBread>().forEach {
            userBreadMap[it.userID] = it
        }
        if (!TimeScheduler.taskMap.keys.contains(name))
            TimeScheduler.taskMap[name] = { time ->
                if (time == "06:00" || time == "12:00" || time == "18:00" || time == "22:00") {
                    userBreadMap.forEach { (_, v) ->
                        v.todayReceive = false
                        v.todayRub = false
                    }
                    UserBread.dailyReset()
                    Logger.logDebug("更新", "抢面包定时更新")
                }
            }
    }

    override suspend fun parse(event: SikaEvent, sika: Sika): LinkedList<Command> {
        val command = LinkedList<Command>()
        if (event is SikaUserEvent) return command
        event as SikaGroupEvent
        if (!FunctionUtils.atBot(event)) return command
        if (!FunctionUtils.checkValid(event)) return command
        if (event.sendGroup.id !in enableGroup) return command
        val param = FunctionUtils.extractKeyword(event, "面包")
        val message = FunctionUtils.extractPlainMessage(event)
        param?.let {
            if (message.contains("买面包")) {
                command.add(Command(event, "$name -Buy", it))
            } else if (message.contains("抢面包")) {
                command.add(Command(event, "$name -Rob", it))
            } else if (message.contains("查询面包")) {
                command.add(Command(event, "$name -Check", it))
            } else {
                command
            }
        }
        return command
    }

    override suspend fun execute(command: Command, sika: Sika): CommandProcessor.Result {
        if (!TimeUtils.checkAdult(Bot.userList[command.sender.id]!!.birthday)) {
            command.sendGroup?.sendMessage("检测到您未成年，请设置生日")
            return CommandProcessor.Result.BLOCK
        }
        synchronized(userBreadMap) {
            // 首先检查是否有该用户
            if (!userBreadMap.keys.contains(command.sender.id)) {
                UserBread(
                    userID = command.sender.id,
                ).let {
                    userBreadMap[command.sender.id] = it
                    Bot.sikaCore.databaseInsert(it)
                }
            }
            val builder = SikaMessageChainBuilder()
            builder.add(SikaAtMessage(command.sender.id))
            when (command.instruction.split(" ")[1]) {
                "-Buy" -> {
                    if (userBreadMap[command.sender.id]!!.todayReceive) {
                        builder.add("你已经买过面包了，过一会再来吧")
                        command.sendGroup?.sendMessage(builder)
                        return CommandProcessor.Result.ADOPT
                    }
                    val num = (3..10).shuffled().last()
                    userBreadMap[command.sender.id]!!.breadNum += num
                    userBreadMap[command.sender.id]!!.todayReceive = true
                    builder.add("你买到了${num}个面包，你现在有${userBreadMap[command.sender.id]!!.breadNum}个面包")
                    command.sendGroup?.sendMessage(builder)
                    Bot.sikaCore.databaseUpdate(userBreadMap[command.sender.id]!!)

                    Operation(command).apply {
                        Bot.sikaCore.databaseInsert(this)
                    }
                }
                "-Rob" -> {
                    if (userBreadMap[command.sender.id]!!.todayRub) {
                        builder.add("你已经抢过面包了，过一会再来吧")
                        command.sendGroup?.sendMessage(builder)
                        return CommandProcessor.Result.ADOPT
                    }
                    if (userBreadMap[command.sender.id]!!.justRub) {
                        builder.add("你又来抢面包了哦，休息一下吧")
                        command.sendGroup?.sendMessage(builder)
                        return CommandProcessor.Result.ADOPT
                    }
                    val num = (3..5).shuffled().last()
                    var success = false
                    var selfRob = Random().nextInt(10) > 7
                    val target: Long = userBreadMap.keys.toLongArray()[Random().nextInt(userBreadMap.size)]
                    if (userBreadMap[target]!!.breadNum > 8 && target != command.sender.id && !selfRob) {
                        userBreadMap[target]!!.breadNum -= num
                        userBreadMap[command.sender.id]!!.breadNum += num
                        Bot.sikaCore.databaseUpdate(userBreadMap[target]!!)
                        Bot.sikaCore.databaseUpdate(userBreadMap[command.sender.id]!!)
                        success = true
                    } else if (target == command.sender.id) {
                        selfRob = true
                    }
                    if (success) {
                        builder.add("你从${Bot.userList[target]!!.name}那里抢到了${num}个面包，你现在有${userBreadMap[command.sender.id]!!.breadNum}个面包")
                        userBreadMap[command.sender.id]!!.todayRub = true
                        Bot.sikaCore.databaseUpdate(userBreadMap[command.sender.id]!!)

                        val operation = Operation(command).apply {
                            Bot.sikaCore.databaseInsert(this)
                        }
                        operation.let {
                            it.target = target
                            OperationDatabaseUtils.operationAddTarget(it)
                        }
                    }
                    if (selfRob) {
                        builder.add("你设了一个陷阱，结果自己掉了进去，谁的面包都没抢到")
                        userBreadMap[command.sender.id]!!.justRub = true
                        Bot.sikaCore.delay(30000) {
                            userBreadMap[command.sender.id]!!.justRub = false
                        }
                    }
                    if (!success && !selfRob) {
                        builder.add("你找到了个抢夺对象，但是他太穷了，还是放过他吧")
                        userBreadMap[command.sender.id]!!.justRub = true
                        Bot.sikaCore.delay(30000) {
                            userBreadMap[command.sender.id]!!.justRub = false
                        }
                    }
                    command.sendGroup?.sendMessage(builder)
                }
                "-Check" -> {
                    builder.add("你现在有${userBreadMap[command.sender.id]!!.breadNum}个面包")
                    command.sendGroup?.sendMessage(builder)
                    Operation(command).apply {
                        Bot.sikaCore.databaseInsert(this)
                    }
                }
            }
            return CommandProcessor.Result.ADOPT
        }
    }
}

@Table("UserBread", "", "userID")
data class UserBread(
    @Column("userID")
    var userID: Long = -1,

    @Column("breadNum")
    var breadNum: Double = -1.0,

    @Column("todayRob")
    var todayRub: Boolean = false,

    @Column("todayReceive")
    var todayReceive: Boolean = false,

    @Column("stock")
    var stock: Int = 0,

    @Column("oweBread")
    var oweBread: Double = 0.0,

    @Column("oweStock")
    var oweStock: Int = 0,

    var justRub: Boolean = false
) {
    companion object {
        fun dailyReset() {
            Bot.sikaCore.getStatement(
                "UPDATE UserBread SET todayReceive = 0, todayRob = 0"
            ).executeUpdate()
        }
    }
}